package com.hilaver.dzmis.web.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.hilaver.dzmis.Constants;
import com.hilaver.dzmis.accesscontrol.AcUser;
import com.hilaver.dzmis.log.Log;
import com.hilaver.dzmis.service.impl.AcUserServiceImpl;
import com.hilaver.dzmis.service.impl.LogServiceImpl;
import com.hilaver.dzmis.util.StringUtils;

/**
 * 
 * 
 */
public class AccessControlFilter implements javax.servlet.Filter {

	private AcUserServiceImpl auService;

	private LogServiceImpl logService;

	public AccessControlFilter() {
		this.auService = new AcUserServiceImpl();
		this.logService = new LogServiceImpl();
	}

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		Log log = new Log();
		
		HttpServletRequest httpReq = (HttpServletRequest) request;
		String ipAddress = getIpAddr(httpReq);
		AcUser acUser = (AcUser) httpReq.getSession().getAttribute(
				Constants.SESSION_USER);
		String uri = httpReq.getRequestURI();
		String relativeURI = getRequestRelativeURI(request);

		try {

			if (!this.auService.isInAcationList(relativeURI)
					&& !"/ui/layout.jsp".equals(relativeURI)) {
				chain.doFilter(request, response);
				return;
			}

			if (acUser == null
					&& (relativeURI.indexOf("login.jsp") == -1 || relativeURI
							.indexOf("index.html") == -1)) {
				request.setAttribute("sessionTimeOut", "sessionTimeOut");
				request.getRequestDispatcher("/ui/login.jsp").forward(request,
						response);
				return;
			}

			if (acUser.getUserName().equals(this.auService.DEFAULT_USER_NAME)
					&& acUser.getUserPwd().equals(
							this.auService.DEFAULT_PASSWORD)) {
				chain.doFilter(request, response);
				return;
			}

			List<String> uriList = (List<String>) httpReq.getSession()
					.getAttribute(Constants.SESSION_ACTION_LIST);
			log.setVisitDate(new Date());
			log.setAcUser(acUser);
			log.setIpAddress(ipAddress);
			log.setActionUrl(relativeURI);
			if (!uriList.contains(relativeURI)
					&& !"/ui/layout.jsp".equals(relativeURI)) {
				log.setIsSuccessful("02");
				this.logService.edit(log);
				request.getRequestDispatcher("/ui/no_permission.jsp").forward(
						request, response);
				return;
			} else {
				log.setIsSuccessful("01");
				this.logService.edit(log);
				chain.doFilter(request, response);
			}
		} catch (Exception e) {
			e.printStackTrace();
			chain.doFilter(request, response);
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

	private static String getRequestRelativeURI(ServletRequest request) {
		HttpServletRequest httpReq = (HttpServletRequest) request;
		String contextPath = httpReq.getContextPath();
		String requestURI = httpReq.getRequestURI();
		String requestRelativeURI = requestURI.substring(requestURI
				.indexOf(contextPath)
				+ contextPath.length());
		String action = httpReq.getParameter("action");
		if (!StringUtils.isEmpty(action))
			requestRelativeURI += "?action=" + action;
		return requestRelativeURI;
	}

	private static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;

	}

}